use std::path::{Path, PathBuf};

/// 工具类 `PathUtil` 用于处理文件路径相关操作
pub struct PathUtil;

impl PathUtil {
    /// 获取文件名
    ///
    /// # 参数
    /// * `path` - 文件路径
    ///
    /// # 返回值
    /// 返回文件名的 `Option`，如果路径无效则返回 `None`
    ///
    /// # 示例
    ///
    /// ```
    /// let file_name = PathUtil::file_name("/some/path/to/file.txt");
    /// log::info!("{:?}", file_name);  // 输出: Some("file.txt")
    /// ```
    pub fn file_name(path: &str) -> Option<String> {
        Path::new(path).file_name().and_then(|s| s.to_str()).map(|s| s.to_owned())
    }

    /// 获取文件扩展名
    ///
    /// # 参数
    /// * `path` - 文件路径
    ///
    /// # 返回值
    /// 返回文件扩展名的 `Option`，如果路径无效或没有扩展名则返回 `None`
    ///
    /// # 示例
    ///
    /// ```
    /// let extension = PathUtil::extension("/some/path/to/file.txt");
    /// log::info!("{:?}", extension);  // 输出: Some("txt")
    /// ```
    pub fn extension(path: &str) -> Option<String> {
        Path::new(path).extension().and_then(|s| s.to_str()).map(|s| s.to_owned())
    }

    /// 获取父目录
    ///
    /// # 参数
    /// * `path` - 文件路径
    ///
    /// # 返回值
    /// 返回父目录的 `Option`，如果路径无效或没有父目录则返回 `None`
    ///
    /// # 示例
    ///
    /// ```
    /// let parent_dir = PathUtil::parent_directory("/some/path/to/file.txt");
    /// log::info!("{:?}", parent_dir);  // 输出: Some("/some/path/to")
    /// ```
    pub fn parent_directory(path: &str) -> Option<String> {
        Path::new(path).parent().and_then(|s| s.to_str()).map(|s| s.to_owned())
    }

    /// 检查路径是否为绝对路径
    ///
    /// # 参数
    /// * `path` - 文件路径
    ///
    /// # 返回值
    /// 如果路径为绝对路径则返回 `true`，否则返回 `false`
    ///
    /// # 示例
    ///
    /// ```
    /// let is_abs = PathUtil::is_absolute("/some/path/to/file.txt");
    /// log::info!("{}", is_abs);  // 输出: true
    /// ```
    pub fn is_absolute(path: &str) -> bool {
        Path::new(path).is_absolute()
    }

    /// 检查路径是否为相对路径
    ///
    /// # 参数
    /// * `path` - 文件路径
    ///
    /// # 返回值
    /// 如果路径为相对路径则返回 `true`，否则返回 `false`
    ///
    /// # 示例
    ///
    /// ```
    /// let is_rel = PathUtil::is_relative("some/relative/path.txt");
    /// log::info!("{}", is_rel);  // 输出: true
    /// ```
    pub fn is_relative(path: &str) -> bool {
        Path::new(path).is_relative()
    }

    /// 连接多个路径片段
    ///
    /// # 参数
    /// * `paths` - 路径片段的切片
    ///
    /// # 返回值
    /// 返回连接后的新路径
    ///
    /// # 示例
    ///
    /// ```
    /// let joined_path = PathUtil::join(&["/some", "path", "to", "file.txt"]);
    /// log::info!("{:?}", joined_path);  // 输出: "/some/path/to/file.txt"
    /// ```
    pub fn join(paths: &[&str]) -> PathBuf {
        let mut result = PathBuf::new();
        for path in paths {
            result.push(path);
        }
        result
    }

    /// 规范化路径
    ///
    /// # 参数
    /// * `path` - 文件路径
    ///
    /// # 返回值
    /// 返回规范化后的路径
    ///
    /// # 示例
    ///
    /// ```
    /// let canonicalized_path = PathUtil::canonicalize("/some/path/to/file.txt");
    /// log::info!("{:?}", canonicalized_path);  // 输出: Some("/some/path/to/file.txt")
    /// ```
    pub fn canonicalize(path: &str) -> Option<PathBuf> {
        match std::fs::canonicalize(path) {
            Ok(p) => Some(p),
            Err(_) => None,
        }
    }

    /// 获取当前工作目录
    ///
    /// # 返回值
    /// 返回当前工作目录的 `Option`，如果获取失败则返回 `None`
    ///
    /// # 示例
    ///
    /// ```
    /// let current_dir = PathUtil::current_directory();
    /// log::info!("{:?}", current_dir);  // 输出: Some("/当前工作目录")
    /// ```
    pub fn current_directory() -> Option<PathBuf> {
        match std::env::current_dir() {
            Ok(p) => Some(p),
            Err(_) => None,
        }
    }
}

fn main() {
    // 初始化日志
    env_logger::init();

    let path = "/some/path/to/file.txt";

    // 获取文件名
    log::info!("File name: {:?}", PathUtil::file_name(path));

    // 获取文件扩展名
    log::info!("Extension: {:?}", PathUtil::extension(path));

    // 获取父目录
    log::info!("Parent directory: {:?}", PathUtil::parent_directory(path));

    // 检查路径是否为绝对路径
    log::info!("Is absolute: {}", PathUtil::is_absolute(path));

    // 检查路径是否为相对路径
    log::info!("Is relative: {}", PathUtil::is_relative(path));

    // 连接多个路径片段
    let joined_path = PathUtil::join(&["/some", "path", "to", "file.txt"]);
    log::info!("Joined path: {:?}", joined_path);

    // 规范化路径
    log::info!("Canonicalized path: {:?}", PathUtil::canonicalize(path));

    // 获取当前工作目录
    log::info!("Current directory: {:?}", PathUtil::current_directory());
}